
import { _decorator, Component, instantiate, Node, NodePool, Prefab, random, Rect } from 'cc';
import { EventName, monster_Refresh_config } from '../../manager/AppControll';
import { DataHelper } from '../../system/DataHelper';
import { Loader } from '../../tools/LoadManger';
import EvtManger from '../../tools/EvtManger';
import { Boss } from './Boss';
import { MonsterNormal } from './MonsterNormal';
import { FightControl, GameModel } from '../FightControl';
import { LevelMonsterManager } from '../levelModel/LevelMonsterManager';
const { ccclass, property } = _decorator;


@ccclass('MonsterManager')
export class MonsterManager {
    private refreshConfig: monster_Refresh_config = null;
    private bIsResh = false;
    private nCurTime = 0;
    private ndMonsterParent: Node = null;
    static ndBoss: Node = null;
    static ltMonster: Node[] = [];
    static normalMonsterPool: NodePool = null;
    static hitNodePool: NodePool = null;
    static hitPrefab: Prefab = null;
    constructor(node: Node) {
        this.ndMonsterParent = node;
        this.refreshConfig = DataHelper.GetMonsterRefreshConfig();
        this.InitHitNodePool();
        this.InitMonsterPool();
        this.RegisteredEvent();
    }

    InitMonsterPool() {
        console.log("InitMonsterPool");
        MonsterManager.normalMonsterPool = new NodePool(MonsterNormal);
        Loader.LoadPrefab("Monster", (prefab) => {
            for (let i = 0; i < 70; i++) {
                let monster = instantiate(prefab);
                monster.addComponent(MonsterNormal);
                MonsterManager.normalMonsterPool.put(monster);
            }
        })
    }

    InitHitNodePool() {
        MonsterManager.hitNodePool = new NodePool();
        Loader.LoadPrefab("hit", (prefab) => {
            MonsterManager.hitPrefab = prefab;
            for (let i = 0; i < 70; i++) {
                let nd = instantiate(MonsterManager.hitPrefab);
                MonsterManager.hitNodePool.put(nd);
            }
        })
    }

    RegisteredEvent() {
        EvtManger.on(EventName.monsterDeath, this, this.UpdateData);
        EvtManger.on(EventName.stageChange, this, this.UpdateData)
    }

    OffEvent() {
        EvtManger.off(EventName.monsterDeath, this, this.UpdateData);
        EvtManger.off(EventName.stageChange, this, this.UpdateData)
    }

    UpdateData() {
        if (this.refreshConfig) {
            if (this.refreshConfig.stageID != DataHelper.GetMonsterRefreshConfig().stageID) {
                EvtManger.do(EventName.monsterRefreshChange);
            }
        }
        this.refreshConfig = DataHelper.GetMonsterRefreshConfig();
    }

    Tick(dt) {
        if (FightControl.gamemodel == GameModel.levelModel) return;

        if (MonsterManager.ltMonster.length < this.refreshConfig.maxMonster) {
            this.bIsResh = true
        } else {
            this.bIsResh = false;
            this.nCurTime = 0;
        }
        if (this.bIsResh) {
            this.nCurTime += dt
        }
        if (this.nCurTime >= this.refreshConfig.refreshInterval) {
            this.CreateMonster();
            this.nCurTime = 0;
        }
    }


    CreateMonster() {
        //console.log("SIZE:" + MonsterManager.normalMonsterPool.size());
        let id = this.GetMonsterID();
        let monsterConfig = DataHelper.GetMonsterBaseConfigById(id);
        if (!monsterConfig) return;
        if (!this.refreshConfig) return;
        let node = MonsterManager.normalMonsterPool.get();
        if (node) {
            this.ndMonsterParent.addChild(node);
            MonsterManager.ltMonster.push(node);
            node.getComponent(MonsterNormal).InitMonster(this.refreshConfig, monsterConfig);
        }

        if (MonsterManager.ndBoss != null) {
            MonsterManager.ndBoss.setSiblingIndex(10000);
        }
    }

    GetMonsterID(): number {
        let pool = this.refreshConfig.monsterPool;
        let totalWeight = 0;
        let weightSum = 0;
        pool.forEach((element) => {
            totalWeight += element[1];
        })
        let randomNumber = Math.random();
        for (let i = 0; i < pool.length; i++) {
            weightSum += pool[i][1];
            if (weightSum >= randomNumber * totalWeight) {
                return pool[i][0];
            }
        }
    }

    CreateBoss() {
        let monsterConfig = DataHelper.GetMonsterBaseConfigById(100017);
        let refreshConfig = DataHelper.GetMonsterRefreshByAuto();
        if (!refreshConfig) return;
        Loader.LoadPrefab("temporaryBoss", (prefab) => {
            if (MonsterManager.ndBoss != null) {
                return;
            }
            let boss = instantiate(prefab);
            this.ndMonsterParent.addChild(boss);
            boss.addComponent(Boss).InitMonster(refreshConfig, monsterConfig);
            MonsterManager.ndBoss = boss;
            MonsterManager.ltMonster.push(boss);
            MonsterManager.ndBoss.setSiblingIndex(10000);
        })
    }

    ChangeLevelMode() {
        MonsterManager.ltMonster.forEach(nd => { MonsterManager.normalMonsterPool.put(nd) });
        MonsterManager.ltMonster = [];
        LevelMonsterManager.ltMonster = [];
        MonsterManager.ndBoss = null;
    }
}
